package partFour;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestReflect5 {
    /*本方法用于练习通过反射创建指定类Student的对象*/
    /*方式一：通过字节码对象之间调用newInstance(),触发目标类的无参构造来创建对象
     * 方式二：先获取指定参数类型的构造函数对象
     *       再通过获取到的这个构造函数对象调用newInsatnce(参数列表)
     *       来创建Student类对象*/
    @Test
    public void getObject() throws Exception {
        //1.获取字节码对象
        Class<?> clazz = Student.class;
        //2.通过反射创建对象
        Object o = clazz.newInstance();//这样已经创建对象了
        System.out.println(o);
        /*以上我们newInstance()触发的是Student类中的无参构造创建对象
         * 所以仅仅能创建对象，但不能给对象的属性赋值
         * 所以，如果需要触发其他的构造函数来创建对象的话
         * 需要先获取指定的构造函数对象*/
        //3.想尝试通过其他的构造函数来创建对象
        //3.1想用其他构造，先得获取，怎么获取？指定参数列表来获取
        /*本方法用于获取指定参数列表的构造函数，获取的是一个构造函数对象
         * 注意，这个方法的参数是目标类Student中对应构造函数的参数类型
         * 而且参入的是字节码对象，不是普通的类型*/
        Constructor<?> c = clazz.getConstructor(String.class,int.class);
        //3.2通过刚刚获取到的构造函数对象来帮我们创建Student类的对象
        Object o2 = c.newInstance("海绵宝宝", 18);
        /*向下转型：之前转成父类类型的子类对象
         * 如果想要使用子类的特有功能，需要重新转回成子类类型
         * 因为父类对象无法使用子类的特有功能*/
        //4.将多态对象转回子类对象--向下转型
        Student s = (Student) o2;
        System.out.println(s.getName());
        System.out.println(s.age);
        s.eat(999);
    }
}